# 主要是需要moviepy这个库
import json
import subprocess
from datetime import datetime, timedelta
from pydub import AudioSegment  # 先导入这个模块
import cv2
from mutagen.aac import AAC
from moviepy.editor import *
import os
import glob2 as gb
from PIL import Image
import pysrt
from DBAction import DBAction


final_foder = './final/'


def combine_video():
    """合并视频"""
    # TODO moviepy太慢，替换为FFmpeg
    video_path_list = gb.glob(os.path.join(r'D:\pocket48image\fanpai', '**/*.mp4'))
    video_list = []
    count = 0
    for path in video_path_list:
        # vc = cv2.VideoCapture(path)
        # print(vc.get(cv2.CAP_PROP_FRAME_WIDTH), vc.get(cv2.CAP_PROP_FRAME_HEIGHT))

        # 载入视频,target_resolution第一个是高度，第二个宽度。一个为None会按比例缩放
        video = VideoFileClip(path, target_resolution=[1000, None])
        # 添加到数组
        print(video.size)
        video_list.append(video)
        count += 1
        if count == 4:
            break

    # 拼接视频
    final_clip = concatenate_videoclips(video_list, method='compose')
    # 生成目标视频文件
    final_clip.write_videofile("./target.mp4", fps=24, threads=2)


def concat_acc_v1(acclist, target_name=None):
    # 连接acclist中的文件，为target_name的aac
    clist = open('./clist.txt', 'wt', encoding='utf-8')
    for acc in acclist:
        clist.write("file '" + acc + "'\n")
    clist.close()
    if target_name is None:
        cmd = 'ffmpeg -f concat -safe 0 -i clist.txt -c copy c1.aac'
    else:
        cmd = f'ffmpeg -f concat -safe 0 -i clist.txt -c copy {target_name}.aac'
    subprocess.call(cmd, shell=True)


def compose_acc(acclist):
    # 不用了
    output_music = None
    for acc in acclist:
        input_music_1 = AudioSegment.from_file(acc, format='aac')
        if output_music is None:
            output_music = input_music_1
        else:
            # 获取两个音频的响度（音量）
            db1 = input_music_1.dBFS
            db2 = output_music.dBFS
            print(db1, db2)
            # 调整两个音频的响度一致
            dbplus = db1 - db2
            if dbplus < 0:  # song1的声音更小
                input_music_1 += abs(dbplus)
            elif dbplus > 0:  # song2的声音更小
                output_music += abs(dbplus)
            output_music = output_music + input_music_1

    # 简单输入合并之后的音频
    output_music.export("./output_music.mp3", format="mp3")


def add_acc_to_mp4():
    os.chdir('./')  # 定位相对路径
    inmp4 = '视频路径'
    inmp3 = '音频路径'
    cmd = f'ffmpeg -i {inmp4} -i {inmp3} -codec copy E:\IDE\pachong\a.mp4'
    subprocess.call(cmd, shell=True)


def getTotalTime(file_path):
    """获取长度，返回秒"""
    audio = AAC(file_path)
    return audio.info.length


sql = """SELECT m.name,m.team,r.msg_type,r.ext_info,r.msg_time 
FROM pocket48.roommsg r 
left join member m on m.memberid=r.memberid 
where r.msg_type in (10) 
and r.msg_time>'2021-06-12 19:00:00' and r.msg_time<='2021-06-22 03:00:00'
and (ext_info like '%%绕口令%%'
or ext_info like '%%挑战%%'
or ext_info like '%%读%%'
or ext_info like '%%说%%'
or ext_info like '%%来一段%%'
or ext_info like '%%念%%'
or ext_info like '%%演绎%%'
or ext_info like '%%一声%%'
or ext_info like '%%说一句%%'
or ext_info like '%%读一下%%'
or ext_info like '%%读一段%%'
or ext_info like '%%念一段%%'
or ext_info like '%%说一段%%'
or ext_info like '%%朗诵%%'
or ext_info like '%%作答%%'
or ext_info like '%%顺口溜%%'
or ext_info like '%%唸%%'
or ext_info like '%%心疼%%'
or ext_info like '%%来段%%'
or ext_info like '%%翻译%%'
or ext_info like '%%语文%%'
or ext_info like '%%盆碰棚%%'
or ext_info like '%%老农%%'
or ext_info like '%%蒸羊羔%%'
or ext_info like '%%炸里脊%%'
or ext_info like '%%施氏%%'
or ext_info like '%%锡匠%%'
or ext_info like '%%棉制服%%'
or ext_info like '%%红鲤鱼%%'
or ext_info like '%%小鸟说%%'
or ext_info like '%%黑化肥%%'
or ext_info like '%%四十%%'
or ext_info like '%%十四%%'
or ext_info like '%%防护服%%'
or ext_info like '%%石狮子%%'
or ext_info like '%%刘奶奶%%'
or ext_info like '%%鹅%%'
or ext_info like '%%牛郎%%'
)
order by m.team,m.fan_num desc,r.msg_time
limit 100000"""


def prepare():
    """
    准备预筛选的内容，包括筛选.srt和连接起来的语音。
    听完语音，将筛选.srt中合适的留下，进行接下来的处理
    """
    db = DBAction('pocket48')
    result = db.data_inquiry_all(sql)
    filepathlist = []
    shaixuan = open('./筛选.srt', 'wt', encoding='utf-8')
    for data in result:
        # m.name,m.team,r.msg_type,r.ext_info,r.msg_time
        member_name = data[0]
        filename = data[4].strftime("%Y-%m-%d_%H-%M-%S") + '.aac'
        path = r'D:\pocket48image\fanpai' + '\\' + member_name + '\\' + filename

        filepathlist.append(path)
        ext = json.loads(data[3])
        ques = ext['question'].replace('\n', '')
        shaixuan.write(member_name + ' ' + path + ' ' + ques + '\n')
    shaixuan.close()
    concat_acc_v1(filepathlist)


def get_zimu_and_acc(team, shailist):
    """筛选完成后，根据筛好的文本文件，来得到字幕和音频，按队伍分p"""
    db = DBAction('pocket48')
    oridir = os.getcwd()
    os.chdir(final_foder)
    # 创建字幕文件，命名规则 队伍.srt
    destScript = open('./' + team + '.srt', 'wt', encoding='utf-8')
    seqNo = 1

    startTime = datetime(1980, 1, 1, 0, 0, 0)
    result = db.data_inquiry_all(sql)
    adjust = False
    filepathlist = []

    for data in result:
        member_name = data[0]
        filename = data[4].strftime("%Y-%m-%d_%H-%M-%S") + '.aac'
        path = r'D:\pocket48image\fanpai' + '\\' + member_name + '\\' + filename
        if path not in shailist:
            continue

        filepathlist.append(path)
        ext = json.loads(data[3])
        ques = ext['question']
        endTime = startTime + timedelta(milliseconds=getTotalTime(path) * 1000)
        if not adjust:
            endTime = endTime - timedelta(milliseconds=500)
            adjust = True
        destScript.write(str(seqNo) + '\n')  # 写字幕序号
        destScript.write(startTime.strftime("%X") + ',0 --> ' + endTime.strftime("%X") + ',0\n')
        destScript.write(member_name + '\n\n' + ques + '\n\n\n')
        destScript.write('\n')
        seqNo += 1
        startTime = endTime
    destScript.close()
    concat_acc_v1(filepathlist, team)
    os.chdir(oridir)


def process_from_shaixuan(shaifile):
    # 由筛选好的文件，经过下面的逻辑，得到字幕和acc文件
    shailist = []
    shaixuan = open(shaifile, 'r', encoding='utf-8')
    lines = shaixuan.readlines()
    team = ''

    os.makedirs(final_foder, exist_ok=True)
    for l in lines:
        splist_list = l.split(' ')
        if len(splist_list) <= 1:  # 空行
            continue
        if splist_list[0] == 'team':
            if len(shailist) != 0:
                get_zimu_and_acc(team, shailist)
            team = splist_list[1].replace('\n', '').replace('\r', '')
            shailist.clear()
        shailist.append(l.split(' ')[1].replace('\n', '').replace('\r', ''))
    if len(shailist) != 0:
        print(team, shailist)
        get_zimu_and_acc(team, shailist)


def print_shaixuan(shaifile):
    # 由筛选好的文件，经过下面的逻辑，得到字幕和acc文件
    shailist = []
    shaixuan = open(shaifile, 'r', encoding='utf-8')
    lines = shaixuan.readlines()
    team = ''

    os.makedirs(final_foder, exist_ok=True)
    for l in lines:
        splist_list = l.split(' ')
        if len(splist_list) <= 1:  # 空行
            continue
        if splist_list[0] == 'team':
            if len(shailist) != 0:
                print(team, shailist)
            team = splist_list[1].replace('\n', '').replace('\r', '')
            shailist.clear()
        if l.split(' ')[0] not in shailist:
            shailist.append(l.split(' ')[0])
    if len(shailist) != 0:
        print(team, shailist)
        print(team, shailist)


def text_file(video, srtname, targetname):
    # 添加字幕文件到视频
    os.chdir('./')  # 定位相对路径

    cmd = f'ffmpeg -i "{video}" -lavfi "subtitles={srtname}.srt:force_style=\'Alignment=2,OutlineColour=&H100000000,' \
          f'BorderStyle=3,Outline=1,Shadow=0,Fontsize= 10,MarginV=3\'" -vcodec h264_nvenc  "{targetname}.mp4"  -y'
    subprocess.call(cmd, shell=True)


def get_p_mp4(image, time, filename, pad_x):
    # 单张图片转视频。pad_x是图片左上角x坐标，一般图片都是长的
    os.chdir('./')
    cmd = f'ffmpeg -ss 0 -t {time} -f lavfi -i color=c=0x000000:s=1920x1080:r=30  ' \
          f'-i {image} ' \
          f'-filter_complex  "[1:v]scale=-1:1080[v1];[0:v][v1]overlay={pad_x}:0[outv]"  ' \
          f'-map [outv] -c:v libx264 {filename}.mp4 -y'
    print(cmd)
    subprocess.call(cmd, shell=False)


def get_person_mp4():
    # TODO 把每个队的都放到文件夹里
    # 找到图片，算出比例，若横着比较长比例大于1920/1080，裁剪到那个比例。否则算出padx
    tarpath = r"D:\pocket_face"
    srt_path_list = gb.glob(os.path.join(r'./final', '**/*.srt'))

    for srt in srt_path_list:
        team = srt.split('\\').pop().replace('.srt', '')
        print(team)

        subs = pysrt.open(srt, encoding='utf-8')
        member_name = ''
        startmin = 0
        startsec = 0
        count = 0
        lastsub = None
        for sub in subs:
            name = sub.text
            lastsub = sub
            if name != member_name:
                if member_name == '':
                    member_name = name
                    continue
                length = 60 * (sub.start.minutes - startmin) + sub.start.seconds - startsec
                # 来到新的名字，把上一个搞出来
                facefolder = os.path.join(tarpath, member_name)
                facepath = gb.glob(os.path.join(facefolder, '*.jpg'))[0]
                img = Image.open(facepath)
                # print(img.size, img.size[0] / img.size[1], 1920/1080.0)
                if img.size[0] / img.size[1] > 1920 / 1080.0:
                    print(img.size[0] / img.size[1])
                    # TODO 裁剪图片
                padx = (1920 - 1080.0 / img.size[1] * img.size[0]) / 2.0
                print(facepath, length, team + '{:2d}'.format(count), padx)
                get_p_mp4(facepath, length, team + str(count).zfill(2), padx)

                # 重置数据
                count += 1
                member_name = name
                startmin = sub.start.minutes
                startsec = sub.start.seconds
        # 最后一个
        length = 60 * (lastsub.end.minutes - startmin) + lastsub.end.seconds - startsec
        facefolder = os.path.join(tarpath, member_name)
        facepath = gb.glob(os.path.join(facefolder, '*.jpg'))[0]
        img = Image.open(facepath)
        if img.size[0] / img.size[1] > 1920 / 1080.0:
            print(img.size[0] / img.size[1])
            # TODO 裁剪图片
        padx = (1920 - 1080.0 / img.size[1] * img.size[0]) / 2.0
        print(facepath, length, team + '{:2d}'.format(count), padx)
        get_p_mp4(facepath, length, team + str(count).zfill(2), padx)


if __name__ == '__main__':
    # prepare()

    # 得到字幕和acc文件。可调整final_folder指定路径
    # process_from_shaixuan('./tmpfile/筛选snh.srt')
    # process_from_shaixuan('./tmpfile/筛选gnz.srt')

    # 根据字幕得到单人的MP4
    # get_person_mp4()

    # 把单人视频合并成队伍的
    teamlist = ['SII', 'NII', 'HII', 'X', 'G', 'NIII', 'Z', '预备生', 'BEJ48']
    # for team in teamlist:
    #     mp4list = gb.glob(os.path.join(r'./', team + '*.mp4'))
    #     if len(mp4list) <= 1:
    #         continue
    #     cmdfile = ''
    #
    #     clist = open('./filelist.txt', 'wt', encoding='utf-8')
    #     for mp4 in mp4list:
    #         clist.write("file '" + mp4 + "'\n")
    #     clist.close()
    #     cmd = f'ffmpeg -f concat -safe 0  -i filelist.txt -c copy {team}.mp4'
    #     print(cmd)
    #     subprocess.call(cmd, shell=False)

    # 把字幕声音合成到队伍mp4中
    # os.chdir('./teamvideo')  # 定位相对路径
    # for team in teamlist:
    #     inmp4 = team + '.mp4'
    #     inmp3 = team + '.aac'
    #     cmd = f'ffmpeg -i {inmp4} -i {inmp3} -codec copy {team}_aac.mp4'
    #     subprocess.call(cmd, shell=True)
    #
    #     cmd = f'ffmpeg -i "{team}_aac.mp4" -lavfi "subtitles={team}.srt:force_style=\'Alignment=2,OutlineColour=&H100000000,' \
    #           f'BorderStyle=3,Outline=1,Shadow=0,Fontsize= 10,MarginV=3\'" -vcodec h264_nvenc  "{team}_final.mp4"  -y'
    #     subprocess.call(cmd, shell=True)
    print_shaixuan('./tmpfile/筛选snh.srt')
    print_shaixuan('./tmpfile/筛选gnz.srt')